package indi.h.security.signature;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

public class SignImp implements Sign {

	protected Signature signature;
	protected String algorithm;
	protected byte[] secureRandom;

	protected SignImp(Signature signature, String algorithm) {
		// TODO Auto-generated constructor stub
		this(signature, algorithm, null);
	}

	protected SignImp(Signature signature, String algorithm, byte[] secureRandom) {
		this.signature = signature;
		this.algorithm = algorithm;
		this.secureRandom = secureRandom;
	}

	public static Sign getInstance(String algorithm, String signAlgorithm, byte[] secureRandom) {
		try {
			return new SignImp(Signature.getInstance(signAlgorithm), algorithm, secureRandom);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public static Sign getInstance(String algorithm, String signAlgorithm, byte[] secureRandom, byte[] publicKey) {
		try {
			SignImp s = new SignImp(Signature.getInstance(signAlgorithm), algorithm, secureRandom);
			s.putUpPrivateKey(publicKey);
			return s;
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public byte[] sign(byte[] data) {
		// TODO Auto-generated method stub
		try {
			signature.update(data);
			return signature.sign();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void putUpPrivateKey(byte[] key) {
		// TODO Auto-generated method stub
		try {
			PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(key);
			KeyFactory kf = KeyFactory.getInstance(algorithm);
			PrivateKey pk = kf.generatePrivate(pkcs);
			if (secureRandom != null) {
				signature.initSign(pk, new SecureRandom(secureRandom));
			} else {
				signature.initSign(pk);
			}
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
